package com.pktechan.manage.aop;

import com.pktechan.manage.utils.DateUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Enumeration;

/**
 * 使用AOP统一处理Web请求日志
 * Created by qx.zhang on 2019/1/30.
 */
@Aspect
@Component
public class WebLogAspect {

    private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    private static ThreadLocal<Date> startTime = new ThreadLocal<Date>();

    @Pointcut("execution(public * com.pktechan.manage.controller.*.*(..))")
    public void webLog() {

    }

    /**
     * 使用AOP前置通知拦截请求参数信息
     *
     * @param joinPoint
     * @throws Throwable
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        //接收到请求，记录日志，记录到nosql中
        //添加截获操作
        startTime.set(new Date());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        StringBuffer msg = new StringBuffer();
        msg.append("\n");
        msg.append("客户端IP：[").append(request.getRemoteAddr()).append("]\n");
        msg.append("客户端HTTPURL：[").append(request.getRequestURL()).append("]\n");
        msg.append("请求方式：[").append(request.getMethod()).append("]\n");
        msg.append("开始执行时间：[").append(DateUtil.getPlusTimeMill(startTime.get())).append("]\n");
        msg.append("SessionId：[").append(request.getSession().getId()).append("]\n");
        msg.append("请求地址：[uri＝").append(request.getRequestURI()).append("]\n");
        Enumeration<String> enumeration = request.getParameterNames();
        msg.append("请求参数：[");
        while (enumeration.hasMoreElements()) {
            String name = (String) enumeration.nextElement();
            String[] values = request.getParameterValues(name);
            msg.append(name).append("=");
            if (values != null) {
                int i = 0;
                for (String value : values) {
                    i++;
                    msg.append(value);
                    if (i < values.length) {
                        msg.append("｜");
                    }
                }
                msg.append("\n");
            }
        }
        msg.append("]");

        //记录在日志文件中
        logger.info(msg.toString());
        //传统写在磁盘上有很大缺点，分布式集群时不方便查询，分布式日志收集系统。延期处理
    }

    @AfterReturning(returning = "obj", pointcut = "webLog()")
    public void doAfterReturning(Object obj) throws Throwable {
        //处理完请求，返回内容
        logger.info("处理完成，返回 : " + obj);
    }
}
